// logger/logger.go
package logger

import (
	"os"
	"path"
	"path/filepath"
	"time"

	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"gopkg.in/natefinch/lumberjack.v2" // 用于日志轮转
)

var (
	Log *zap.Logger // 应用日志
	Api *zap.Logger // API日志
)

// InitLoggerWithPath 使用指定路径初始化日志
func InitLoggerWithPath(logPath string, fileName string) {
	// 确保日志目录存在
	if err := os.MkdirAll(logPath, 0755); err != nil {
		panic("Failed to create log directory: " + err.Error())
	}

	// 配置 zapcore.EncoderConfig
	encoderConfig := zapcore.EncoderConfig{
		TimeKey:        "time",
		LevelKey:       "level",
		NameKey:        "logger",
		CallerKey:      "caller",
		MessageKey:     "msg",
		StacktraceKey:  "stacktrace",
		LineEnding:     zapcore.DefaultLineEnding,
		EncodeLevel:    zapcore.CapitalLevelEncoder,
		EncodeTime:     timeEncoder,
		EncodeDuration: zapcore.SecondsDurationEncoder,
		EncodeCaller:   zapcore.ShortCallerEncoder,
	}

	// 创建轮转日志写入器
	logWriter := &lumberjack.Logger{
		Filename:   path.Join(logPath, fileName), // 日志文件路径
		MaxSize:    100,                          // 单个文件最大尺寸，单位 MB
		MaxBackups: 60,                           // 保留的旧文件最大数量
		MaxAge:     30,                           // 保留的旧文件最大天数
		Compress:   true,                         // 是否压缩旧文件
	}

	// API日志写入器
	apiLogWriter := &lumberjack.Logger{
		Filename:   path.Join(logPath, "api_"+fileName),
		MaxSize:    100,
		MaxBackups: 60,
		MaxAge:     30,
		Compress:   true,
	}

	// 创建核心
	core := zapcore.NewCore(
		zapcore.NewJSONEncoder(encoderConfig),
		zapcore.AddSync(logWriter),
		zap.InfoLevel,
	)

	apiCore := zapcore.NewCore(
		zapcore.NewJSONEncoder(encoderConfig),
		zapcore.AddSync(apiLogWriter),
		zap.InfoLevel,
	)

	// 创建Logger
	Log = zap.New(core, zap.AddCaller())
	Api = zap.New(apiCore, zap.AddCaller())

	Log.Info("Logger initialized",
		zap.String("logPath", logPath),
		zap.String("fileName", fileName))
}

// timeEncoder 自定义时间编码器
func timeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
    enc.AppendString(t.Format("2006-01-02 15:04:05.000"))
}


func InitLogger() {
	// 创建日志目录
	logDir := "logs"
	if err := os.MkdirAll(logDir, 0755); err != nil {
		panic("can't create log directory: " + err.Error())
	}
	// 创建基础配置
	encoderConfig := zapcore.EncoderConfig{
		TimeKey:       "time",
		LevelKey:      "level",
		NameKey:       "logger",
		CallerKey:     "caller",
		MessageKey:    "msg",
		StacktraceKey: "stacktrace",
		LineEnding:    zapcore.DefaultLineEnding,
		EncodeLevel:   zapcore.LowercaseLevelEncoder,
		EncodeTime: func(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
			enc.AppendString(t.Format("2006-01-02 15:04:05.000"))
		},
		EncodeCaller: zapcore.ShortCallerEncoder,
	}

	// 创建轮转日志文件
	appLogFile := &lumberjack.Logger{
		Filename:   filepath.Join(logDir, "app.log"),
		MaxSize:    100,  // MB
		MaxBackups: 30,   // 保留30个备份
		MaxAge:     7,    // 保留7天
		Compress:   true, // 压缩
	}

	apiLogFile := &lumberjack.Logger{
		Filename:   filepath.Join(logDir, "api.log"),
		MaxSize:    100,
		MaxBackups: 30,
		MaxAge:     7,
		Compress:   true,
	}

	// 创建Core
	appCore := zapcore.NewCore(
		zapcore.NewJSONEncoder(encoderConfig),
		zapcore.NewMultiWriteSyncer(zapcore.AddSync(appLogFile), zapcore.AddSync(os.Stdout)),
		zap.InfoLevel,
	)

	apiCore := zapcore.NewCore(
		zapcore.NewJSONEncoder(encoderConfig),
		zapcore.NewMultiWriteSyncer(zapcore.AddSync(apiLogFile)),
		zap.InfoLevel,
	)

	// 创建Logger
	Log = zap.New(appCore, zap.AddCaller(), zap.AddCallerSkip(1))
	Api = zap.New(apiCore)
}

// 包装常用日志方法
func Info(msg string, fields ...zap.Field) {
	Log.Info(msg, fields...)
}

func Error(msg string, fields ...zap.Field) {
	Log.Error(msg, fields...)
}

func Debug(msg string, fields ...zap.Field) {
	Log.Debug(msg, fields...)
}

func Fatal(msg string, fields ...zap.Field) {
	Log.Fatal(msg, fields...)
}

// API日志方法
func LogAPI(method, path string, statusCode int, latency time.Duration) {
	Api.Info("API Request",
		zap.String("method", method),
		zap.String("path", path),
		zap.Int("status", statusCode),
		zap.Duration("latency", latency),
	)
}
